    <h1 class="pageHeader">Spica Framework - Manual - Hand-on guide</h1>

    <h2 class="header">Khai báo Controller và xử lý request trong controller</h2>
    <p>Chúng ta đã làm quen với khái niệm Controller qua bài 
    <a href="docs/guide/page/pname/concept_controller" class="hasIcon">Khái niệm về Controller</a>
    và <a href="docs/guide/page/pname/tutorial_appstructure" class="hasIcon">Khái quát về cấu trúc ứng dụng và thư mục</a>. 
    Trong  bài này, chúng ta sẽ tìm hiểu cách thức tạo ra một lớp Controller thực sự trong một ứng dụng.</p>

    <p>Trong bài <a href="docs/guide/page/pname/tutorial_helloworld" class="hasIcon">Viết ứng dụng đơn giản với Hello World</a> chúng ta đã cùng
    tìm hiểu về cách thức viết một ứng dụng đơn giản chỉ in ra dòng chữ &quot;Hello World&quot;</p>
<pre class="brush: php">
&lt;?php

/**
 * &quot;Hello World&quot; program controller.
 */
 class Base_SampleIndex
 {
     public function helloworldAction()
     {
         SpicaResponse::setBody('Hello World');
     }
 }

?&gt;

</pre>
    <p>Lớp <code>Base_SampleIndex</code> chính là một Controller. 
    Controller được khai báo như là một PHP class bình thường, không cần mở rộng bất 
    cứ một lớp đặc biệt nào. Tuy nhiên tên của lớp này có cấu trúc đặc biệt mà chúng ta
    đã nhắc đến ở <a href="docs/guide/page/pname/tutorial_helloworld" class="hasIcon">Viết ứng dụng đơn giản với Hello World</a>. Theo đó
    tên Controller phản ánh 3 bộ phận: </p>
    <ul>
      <li><code>Base_</code> phản ánh nó thuộc về profile có tên là <code>base</code></li>
      <li><code>Sample</code> phản ánh nó thuộc về module có tên là <code>sample</code></li>
      <li><code>Index</code> phản ánh tên của Controller thực chất là <code>index</code></li>    
    </ul>
    <p>Tên của Controller class sẽ phải trùng với tên file. Ví dụ: tên lớp là <code>Base_SampleIndex</code>
    thì tên file là <code>Base_SampleIndex.php</code></p>
    
    <div class="image">
      <img src="public/spica/screenshot/spica-controller-structure.png" />
      <div class="caption">Hình 1: Vị trí đặt các file Controller trong một Spica application</div>
    </div>
        
    <p>Hình trên cho thấy cách xác định vị trí đặt Controller class có tên là <code>Base_SampleIndex</code> bên trong 
    một ứng dụng có tên là <code>default</code> (thư mục <code>apps/default</code>). Tất cả các Controller class 
    đều nằm trong một thư mục con có tên là controller của ứng dụng này (thư mục <code>apps/default/controller</code>). 
    Trong thư mục này, các controller class sẽ được phân chia thành các profile, mỗi profile là một thư mục con của 
    <code>apps/default/controller</code>. Ví dụ profile có tên là <code>default</code> sẽ có thư mục là 
    <code>apps/default/controller/default</code>. Mỗi profile sẽ lại tiếp tục chia thành các module. Mỗi module 
    là một thư mục con của profile mẹ của nó. Ví dụ module <code>sample</code> nằm trong profile <code>default</code>
    có thư mục là <code>apps/default/controller/default/sample</code>. Bên trong các thư mục module này là các file
    có đuôi là <code>.php</code> chứa các Controller class. Ví dụ <code>Base_SampleIndex.php</code>. </p>
    
    <p>Bên trong lớp Controller, chúng ta sẽ khái báo các phương thức public đặc biệt có tên kết
    thúc bằng hậu tố <code>Action</code>. Đây là một quy ước tên đặc biệt để phương thức dạng 
    này có thể gọi được thông qua URL nhằm giúp Controller trực tiếp đối diện với user request.
    Tất cả các phương thức private, protected hay public mà không có tên kết thúc bằng <code>Action</code>
    đều chỉ có thể gọi từ nội bộ Controller đó hay bên trong code của Spica framework chứ không được
    hiểu là có thể gọi từ URL. Ví dụ: URL dạng <code>sample/index/helloworld</code> khi gửi đến 
    Spica sẽ khiến phương thức <code>Base_SampleIndex::helloworldAction()</code> được gọi. Thành phần 
    profile (ví dụ <code>welcome</code>) là thành phần không tham gia vào URL mà nó được 
    cấu hình ngầm trong hệ thống.</p>    
    
    <p>Một lớp Controller thường chứa nhiều method có tên kết thúc bằng Action và chúng 
    chính là điểm vào chương trình và đó là nơi HTML page được sinh ra.</p>

<pre class="brush: php">
&lt;?php

/**
 * &quot;Hello World&quot; program controller.
 */
 class Base_SampleIndex
 {
     /**
      * @link http://mydomain.com/sample/index/helloworld
      */
     public function helloworldAction()
     {
         SpicaResponse::setBody('Hello World');
     }
     
     /**
      * @link http://mydomain.com/sample/index/mypage1
      */     
     public function mypage1Action()
     {
         SpicaResponse::setBody('My page 1');
     }  
     
     /**
      * @link http://mydomain.com/sample/index/mypage2
      */     
     public function mypage2Action()
     {
         SpicaResponse::setBody('My page 2');
     }
 }

?&gt;

</pre>
    <h3>Xử lý request trong action method</h3>
    <p>Khi user gõ vào thanh địa chỉ (address bar) của trình duyệt để tải về trang web có URL 
    <code>http://mydomain.com/sample/index/helloworld</code> thì Spica sẽ thực hiện toàn 
    bộ các dòng code nằm bên trong phương thức <code>Base_SampleIndex::helloworldAction()</code>. 
    Tuy nhiên, <code>helloworldAction()</code> chỉ là nơi điều phối các lớp ứng dụng 
    khác để sinh ra HTML chứ không trả về HTML một cách trực tiếp cho trình duyệt thông qua
    giao thức HTTP. Một phương thức action thông thường trông như sau: </p>
    
<pre class="brush: php; highlight: [16];">
&lt;?php

/**
 * &quot;Hello World&quot; program controller.
 */
 class Base_SampleIndex
 {
     /**
      * @link http://mydomain.com/sample/index/action1
      */
     public function action1Action()
     {
        $theme = SpicaContext::getTheme();
        $theme-&gt;pageTitle = 'Spica Framework - Manual - Basic guide';
        $theme-&gt;setBody('welcome/SpicaDocsGuideIndexBlockGroup');
        SpicaResponse::setBody($theme-&gt;fetch('vi_VN/guide'));
     }
 }

?&gt;

</pre>    
    <p>Đoạn code <code>$theme-&gt;fetch('vi_VN/guide')</code> (dòng 16) thực thi các code PHP có trên trang 
    (Xem bài <a href="docs/guide/page/pname/howto_layout" class="hasIcon">Làm việc với layout và theme</a>) 
    và trả lại một string chứa mã HTML cho toàn bộ trang nhưng không in chúng ra. Thay vào đó, giá trị 
    này được truyền vào <code>SpicaResponse</code>, một lớp có chức năng xử lý giao thức HTTP và trả lại 
    cho trình duyệt. Tất cả những câu lệnh nào in ra string bên trong phương thức action sẽ được ghi vào 
    một file có tên là <code>message.log</code> nằm trong thư mục <code>log</code> 
    chứ không in ra thẳng màn hình. Những gì in ra màn hình chính là những gì chứa trong <code>SpicaResponse</code>
    thông qua phương thức <code>SpicaResponse::setBody()</code>.</p>

    <?php echo $this->fetchBlock('welcome/SpicaDocsNoteBlock'); ?>